﻿#pragma once

#include <Eigen/Dense>
#include <Eigen/Sparse>

#include <xy/alg/integrator.h>
#include <xy/geom/nurbs.h>

namespace xy
{

namespace alg
{

struct coeff_matrix
{
    /**
     * @brief 计算曲线最小二乘系数矩阵
     *
     * @param[in] params
     * @param[in] knots
     * @param[in] p
     * @return Eigen::SparseMatrix<double>
     */
    static Eigen::SparseMatrix<double> curve_least_square(const std::vector<double> &params,
                                                          const std::vector<double> &knots, std::size_t p);

    /**
     * @brief 计算曲线拉伸-弯曲系数矩阵
     *
     * @param[in] knots
     * @param[in] p
     * @return std::array<Eigen::SparseMatrix<double>, 2>
     */
    static std::array<Eigen::SparseMatrix<double>, 2> curve_stretch_bending(const std::vector<double> &knots,
                                                                            std::size_t p);

    /**
     * @brief 计算曲面最小二乘系数矩阵
     *
     * @param[in] params
     * @param[in] uKnots
     * @param[in] vKnots
     * @param[in] p
     * @param[in] q
     * @return Eigen::SparseMatrix<double>
     */
    static Eigen::SparseMatrix<double> surface_least_square(const std::vector<geom::vec2> &params,
                                                            const std::vector<double> &uKnots,
                                                            const std::vector<double> &vKnots, std::size_t p,
                                                            std::size_t q);

    /**
     * @brief 计算曲面拉伸-弯曲系数矩阵
     *
     * @param[in] uKnots
     * @param[in] vKnots
     * @param[in] p
     * @param[in] q
     * @return std::array<Eigen::SparseMatrix<double>, 2>
     */
    static std::array<Eigen::SparseMatrix<double>, 2> surface_stretch_bending(const std::vector<double> &uKnots,
                                                                              const std::vector<double> &vKnots,
                                                                              std::size_t p, std::size_t q);
};

} // namespace alg

} // namespace xy